home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 2010 Software/Programs / PCGuia_programas.iso / Software / Linux / Fedora 12 / Installer / Fedora-12-i686-Live.iso / LiveOS / livecd-iso-to-disk next >
Encoding:
Text File  |  2009-11-09  |  22.5 KB  |  764 lines

  1. #!/bin/bash
  2. # Convert a live CD iso so that it's bootable off of a USB stick
  3. # Copyright 2007  Red Hat, Inc.
  4. # Jeremy Katz <katzj@redhat.com>
  5. #
  6. # overlay/persistence enhancements by Douglas McClendon <dmc@viros.org>
  7. # GPT+MBR hybrid enhancements by Stewart Adam <s.adam@diffingo.com>
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; version 2 of the License.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU Library General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20.  
  21.  
  22. export PATH=/sbin:/usr/sbin:$PATH
  23.  
  24. usage() {
  25.     echo "$0 [--format] [--reset-mbr] [--noverify] [--overlay-size-mb <size>] [--home-size-mb <size>] [--unencrypted-home] [--skipcopy] <isopath> <usbstick device>"
  26.     exit 1
  27. }
  28.  
  29. cleanup() {
  30.     sleep 2
  31.     [ -d "$CDMNT" ] && umount $CDMNT && rmdir $CDMNT
  32.     [ -d "$USBMNT" ] && umount $USBMNT && rmdir $USBMNT
  33. }
  34.  
  35. exitclean() {
  36.     echo "Cleaning up to exit..."
  37.     cleanup
  38.     exit 1
  39. }
  40.  
  41. getdisk() {
  42.     DEV=$1
  43.  
  44.     if [[ "$DEV" =~ "/dev/loop*" ]]; then
  45.        device="$DEV"
  46.        return
  47.     fi
  48.  
  49.     p=$(udevadm info -q path -n $DEV)
  50.     if [ -e /sys/$p/device ]; then
  51.     device=$(basename /sys/$p)
  52.     else
  53.     device=$(basename $(readlink -f /sys/$p/../))
  54.     fi
  55.     if [ ! -e /sys/block/$device -o ! -e /dev/$device ]; then
  56.     echo "Error finding block device of $DEV.  Aborting!"
  57.     exitclean
  58.     fi
  59.  
  60.     device="/dev/$device"
  61.     # FIXME: weird dev names could mess this up I guess
  62.     p=/dev/`basename $p`
  63.     partnum=${p##$device}
  64. }
  65.  
  66. resetMBR() {
  67.     if [[ "$DEV" =~ "/dev/loop*" ]]; then
  68.        return
  69.     fi
  70.     getdisk $1
  71.     # if efi, we need to use the hybrid MBR
  72.     if [ -n "$efi" ];then
  73.       if [ -f /usr/lib/syslinux/gptmbr.bin ]; then
  74.         gptmbr='/usr/lib/syslinux/gptmbr.bin'
  75.       elif [ -f /usr/share/syslinux/gptmbr.bin ]; then
  76.         gptmbr='/usr/share/syslinux/gptmbr.bin'
  77.       else
  78.         echo "Could not find gptmbr.bin (syslinux)"
  79.         exitclean
  80.       fi
  81.       # our magic number is LBA-2, offset 16 - (512+512+16)/$bs
  82.       dd if=$device bs=16 skip=65 count=1 | cat $gptmbr - > $device
  83.     else
  84.       if [ -f /usr/lib/syslinux/mbr.bin ]; then
  85.         cat /usr/lib/syslinux/mbr.bin > $device
  86.       elif [ -f /usr/share/syslinux/mbr.bin ]; then
  87.         cat /usr/share/syslinux/mbr.bin > $device
  88.       else
  89.         echo "Could not find mbr.bin (syslinux)"
  90.         exitclean
  91.       fi
  92.     fi
  93. }
  94.  
  95. checkMBR() {
  96.     if [[ "$DEV" =~ "/dev/loop*" ]]; then
  97.        return 0
  98.     fi
  99.     getdisk $1
  100.  
  101.     bs=$(mktemp /tmp/bs.XXXXXX)
  102.     dd if=$device of=$bs bs=512 count=1 2>/dev/null || exit 2
  103.     
  104.     mbrword=$(hexdump -n 2 $bs |head -n 1|awk {'print $2;'})
  105.     rm -f $bs
  106.     if [ "$mbrword" = "0000" ]; then
  107.     echo "MBR appears to be blank."
  108.     echo "Do you want to replace the MBR on this device?"
  109.     echo "Press Enter to continue or ctrl-c to abort"
  110.     read
  111.     resetMBR $1
  112.     fi
  113.  
  114.     return 0
  115. }
  116.  
  117. checkPartActive() {
  118.     dev=$1
  119.     getdisk $dev
  120.     
  121.     # if we're installing to whole-disk and not a partition, then we 
  122.     # don't need to worry about being active
  123.     if [ "$dev" = "$device" ]; then
  124.     return
  125.     fi
  126.     if [[ "$dev" =~ "/dev/loop*" ]]; then
  127.         return
  128.     fi
  129.  
  130.     if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep $dev |awk {'print $2;'})" != "*" ]; then
  131.     echo "Partition isn't marked bootable!"
  132.     echo "You can mark the partition as bootable with "
  133.         echo "    # /sbin/parted $device"
  134.     echo "    (parted) toggle N boot"
  135.     echo "    (parted) quit"
  136.     exitclean
  137.     fi
  138. }
  139.  
  140. createGPTLayout() {
  141.     dev=$1
  142.     getdisk $dev
  143.  
  144.     echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
  145.     echo "Press Enter to continue or ctrl-c to abort"
  146.     read
  147.     umount ${device}? &> /dev/null
  148.     /sbin/parted --script $device mklabel gpt
  149.     partinfo=$(/sbin/parted --script -m $device "unit b print" |grep ^$device:)
  150.     size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
  151.     /sbin/parted --script $device unit b mkpart '"EFI System Partition"' fat32 17408 $(($size - 17408)) set 1 boot on
  152.     USBDEV=${device}1
  153.     # Sometimes automount can be _really_ annoying.
  154.     echo "Waiting for devices to settle..."
  155.     /sbin/udevadm settle
  156.     sleep 5
  157.     umount $USBDEV &> /dev/null
  158.     /sbin/mkdosfs -n LIVE $USBDEV
  159.     USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
  160. }
  161.  
  162. createMSDOSLayout() {
  163.     dev=$1
  164.     getdisk $dev
  165.  
  166.     echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
  167.     echo "Press Enter to continue or ctrl-c to abort"
  168.     read
  169.     umount ${device}? &> /dev/null
  170.     /sbin/parted --script $device mklabel msdos
  171.     partinfo=$(/sbin/parted --script -m $device "unit b print" |grep ^$device:)
  172.     size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
  173.     /sbin/parted --script $device unit b mkpart primary fat32 17408 $(($size - 17408)) set 1 boot on
  174.     USBDEV=${device}1
  175.     # Sometimes automount can be _really_ annoying.
  176.     echo "Waiting for devices to settle..."
  177.     /sbin/udevadm settle
  178.     sleep 5
  179.     umount $USBDEV &> /dev/null
  180.     /sbin/mkdosfs -n LIVE $USBDEV
  181.     USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
  182. }
  183.  
  184. checkGPT() {
  185.     dev=$1
  186.     getdisk $dev
  187.  
  188.     if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep -c GPT)" -eq "0" ]; then
  189.        echo "EFI boot requires a GPT partition table."
  190.        echo "This can be done manually or you can run with --format"
  191.        exitclean
  192.     fi
  193.  
  194.     partinfo=$(/sbin/parted --script -m $device "print" |grep ^$partnum:)
  195.     volname=$(echo $partinfo |cut -d : -f 6)
  196.     flags=$(echo $partinfo |cut -d : -f 7)
  197.     if [ "$volname" != "EFI System Partition" ]; then
  198.     echo "Partition name must be 'EFI System Partition'"
  199.     echo "This can be set in parted or you can run with --reset-mbr"
  200.     exitclean
  201.     fi
  202.     if [ "$(echo $flags |grep -c boot)" = "0" ]; then
  203.     echo "Partition isn't marked bootable!"
  204.     echo "You can mark the partition as bootable with "
  205.         echo "    # /sbin/parted $device"
  206.     echo "    (parted) toggle N boot"
  207.     echo "    (parted) quit"
  208.     exitclean
  209.     fi
  210. }
  211.  
  212. checkFilesystem() {
  213.     dev=$1
  214.  
  215.     USBFS=$(/sbin/blkid -s TYPE -o value $dev)
  216.     if [ "$USBFS" != "vfat" -a "$USBFS" != "msdos" -a "$USBFS" != "ext2" -a "$USBFS" != "ext3" ]; then
  217.     echo "USB filesystem must be vfat or ext[23]"
  218.     exitclean
  219.     fi
  220.  
  221.     USBLABEL=$(/sbin/blkid -s UUID -o value $dev)
  222.     if [ -n "$USBLABEL" ]; then 
  223.     USBLABEL="UUID=$USBLABEL" ; 
  224.     else
  225.     USBLABEL=$(/sbin/blkid -s LABEL -o value $dev)
  226.     if [ -n "$USBLABEL" ]; then 
  227.         USBLABEL="LABEL=$USBLABEL" 
  228.     else
  229.         echo "Need to have a filesystem label or UUID for your USB device"
  230.         if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
  231.         echo "Label can be set with /sbin/dosfslabel"
  232.         elif [ "$USBFS" = "ext2" -o "$USBFS" = "ext3" ]; then
  233.         echo "Label can be set with /sbin/e2label"
  234.         fi
  235.         exitclean
  236.     fi
  237.     fi
  238.  
  239.     if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
  240.     mountopts="-o shortname=winnt,umask=0077"
  241.     fi
  242. }
  243.  
  244. checkSyslinuxVersion() {
  245.     if [ ! -x /usr/bin/syslinux ]; then
  246.     echo "You need to have syslinux installed to run this script"
  247.     exit 1
  248.     fi
  249.     if ! syslinux 2>&1 | grep -qe -d; then
  250.     SYSLINUXPATH=""
  251.     elif [ -n "$multi" ]; then
  252.     SYSLINUXPATH="$LIVEOS/syslinux"
  253.     else
  254.     SYSLINUXPATH="syslinux"
  255.     fi
  256. }
  257.  
  258. checkMounted() {
  259.     dev=$1
  260.     if grep -q "^$dev " /proc/mounts ; then
  261.       echo "$dev is mounted, please unmount for safety"
  262.       exitclean
  263.     fi
  264.     if grep -q "^$dev " /proc/swaps; then
  265.       echo "$dev is in use as a swap device, please disable swap"
  266.       exitclean
  267.     fi
  268. }
  269.  
  270. checkint() {
  271.     if ! test $1 -gt 0 2>/dev/null ; then
  272.     usage
  273.     fi
  274. }
  275.  
  276. if [ $(id -u) != 0 ]; then 
  277.     echo "You need to be root to run this script"
  278.     exit 1
  279. fi
  280.  
  281. detectisotype() {
  282.     if [ -e $CDMNT/LiveOS/squashfs.img ]; then
  283.         isotype=live
  284.         return
  285.     fi
  286.     if [ -e $CDMNT/images/install.img ]; then
  287.         isotype=installer
  288.         return
  289.     fi
  290.     echo "ERROR: $ISO does not appear to be a Live image or DVD installer."
  291.     exitclean
  292. }
  293.  
  294. cryptedhome=1
  295. keephome=1
  296. homesizemb=0
  297. swapsizemb=0
  298. overlaysizemb=0
  299. isotype=
  300. LIVEOS=LiveOS
  301.  
  302. HOMEFILE="home.img"
  303. while [ $# -gt 2 ]; do
  304.     case $1 in
  305.     --overlay-size-mb)
  306.         checkint $2
  307.         overlaysizemb=$2
  308.         shift
  309.         ;;
  310.     --home-size-mb)
  311.         checkint $2
  312.             homesizemb=$2
  313.             shift
  314.         ;;
  315.     --swap-size-mb)
  316.         checkint $2
  317.         swapsizemb=$2
  318.         shift
  319.         ;;
  320.         --crypted-home)
  321.             cryptedhome=1
  322.         ;;
  323.         --unencrypted-home)
  324.             cryptedhome=""
  325.             ;;
  326.         --delete-home)
  327.             keephome=""
  328.             ;;
  329.     --noverify)
  330.         noverify=1
  331.         ;;
  332.     --reset-mbr|--resetmbr)
  333.         resetmbr=1
  334.         ;;
  335.     --efi|--mactel)
  336.         efi=1
  337.         ;;
  338.     --format)
  339.         format=1
  340.         ;;
  341.     --skipcopy)
  342.         skipcopy=1
  343.         ;;
  344.     --xo)
  345.         xo=1
  346.         skipcompress=1
  347.         ;;
  348.     --xo-no-home)
  349.         xonohome=1
  350.         ;;
  351.     --compress)
  352.         skipcompress=""
  353.         ;;
  354.     --skipcompress)
  355.         skipcompress=1
  356.         ;;
  357.         --extra-kernel-args)
  358.             kernelargs=$2
  359.             shift
  360.             ;;
  361.         --force)
  362.             force=1
  363.             ;;
  364.     --livedir)
  365.         LIVEOS=$2
  366.         shift
  367.         ;;
  368.     --multi)
  369.         multi=1
  370.         ;;
  371.     *)
  372.         echo "invalid arg -- $1"
  373.         usage
  374.         ;;
  375.     esac
  376.     shift
  377. done
  378.  
  379. ISO=$(readlink -f "$1")
  380. USBDEV=$(readlink -f "$2")
  381.  
  382. if [ -z "$ISO" ]; then
  383.     usage
  384. fi
  385.  
  386. if [ ! -b "$ISO" -a ! -f "$ISO" ]; then
  387.     usage
  388. fi
  389.  
  390. # FIXME: If --format is given, we shouldn't care and just use /dev/foo1
  391. if [ -z "$USBDEV" -o ! -b "$USBDEV" ]; then
  392.     usage
  393. fi
  394.  
  395. if [ -z "$noverify" ]; then
  396.     # verify the image
  397.     echo "Verifying image..."
  398.     checkisomd5 --verbose "$ISO"
  399.     if [ $? -ne 0 ]; then
  400.     echo "Are you SURE you want to continue?"
  401.     echo "Press Enter to continue or ctrl-c to abort"
  402.     read
  403.     fi
  404. fi
  405.  
  406. # do some basic sanity checks.  
  407. checkMounted $USBDEV
  408. if [ -n "$format" ];then
  409.   # checks for a valid filesystem
  410.   if [ -n "$efi" ];then
  411.     createGPTLayout $USBDEV
  412.   else
  413.     createMSDOSLayout $USBDEV
  414.   fi
  415. fi
  416. checkFilesystem $USBDEV
  417. if [ -n "$efi" ]; then
  418.   checkGPT $USBDEV
  419. fi
  420. checkSyslinuxVersion
  421. # Because we can't set boot flag for EFI Protective on msdos partition tables
  422. [ -z "$efi" ] && checkPartActive $USBDEV
  423. [ -n "$resetmbr" ] && resetMBR $USBDEV
  424. checkMBR $USBDEV
  425.  
  426.  
  427. if [ "$overlaysizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  428.   if [ "$overlaysizemb" -gt 2047 ]; then
  429.     echo "Can't have an overlay of 2048MB or greater on VFAT"
  430.     exitclean
  431.   fi
  432. fi
  433.  
  434. if [ "$homesizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  435.   if [ "$homesizemb" -gt 2047 ]; then
  436.     echo "Can't have a home overlay greater than 2048MB on VFAT"
  437.     exitclean
  438.   fi
  439. fi
  440.  
  441. if [ "$swapsizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  442.   if [ "$swapsizemb" -gt 2047 ]; then
  443.     echo "Can't have a swap file greater than 2048MB on VFAT"
  444.     exitclean
  445.   fi
  446. fi
  447.  
  448. # FIXME: would be better if we had better mountpoints
  449. CDMNT=$(mktemp -d /media/cdtmp.XXXXXX)
  450. mount -o loop,ro "$ISO" $CDMNT || exitclean
  451. USBMNT=$(mktemp -d /media/usbdev.XXXXXX)
  452. mount $mountopts $USBDEV $USBMNT || exitclean
  453.  
  454. trap exitclean SIGINT SIGTERM
  455.  
  456. detectisotype
  457.  
  458. if [ -f "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a "$homesizemb" -gt 0 ]; then
  459.   echo "ERROR: Requested keeping existing /home and specified a size for /home"
  460.   echo "Please either don't specify a size or specify --delete-home"
  461.   exitclean
  462. fi
  463.  
  464. if [ -n "$efi" -a ! -d $CDMNT/EFI/boot ]; then
  465.   echo "ERROR: This live image does not support EFI booting"
  466.   exitclean
  467. fi
  468.  
  469. # let's try to make sure there's enough room on the stick
  470. if [ -d $CDMNT/LiveOS ]; then
  471.   check=$CDMNT/LiveOS
  472. else
  473.   check=$CDMNT
  474. fi
  475. if [ -d $USBMNT/$LIVEOS ]; then
  476.   tbd=$(du -s -B 1M $USBMNT/$LIVEOS | awk {'print $1;'})
  477.   [ -f $USBMNT/$LIVEOS/$HOMEFILE ] && homesz=$(du -s -B 1M $USBMNT/$LIVEOS/$HOMEFILE | awk {'print $1;'})
  478.   [ -n "$homesz" -a -n "$keephome" ] && tbd=$(($tbd - $homesz))
  479. else
  480.   tbd=0
  481. fi
  482. livesize=$(du -s -B 1M $check | awk {'print $1;'})
  483. if [ -n "$skipcompress" ]; then
  484.     if [ -e $CDMNT/LiveOS/squashfs.img ]; then
  485.     if mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT; then
  486.         livesize=$(du -s -B 1M $CDMNT/LiveOS/ext3fs.img | awk {'print $1;'})
  487.         umount $CDMNT
  488.     else
  489.         echo "WARNING: --skipcompress or --xo was specified but the currently"
  490.         echo "running kernel can not mount the squashfs from the ISO file to extract"
  491.         echo "it. The compressed squashfs will be copied to the USB stick."
  492.         skipcompress=""
  493.     fi
  494.     fi
  495. fi
  496. free=$(df  -B1M $USBDEV  |tail -n 1 |awk {'print $4;'})
  497.  
  498. if [ "$isotype" = "live" ]; then
  499. tba=$(($overlaysizemb + $homesizemb + $livesize + $swapsizemb))
  500. if [ $tba -gt $(($free + $tbd)) ]; then
  501.   echo "Unable to fit live image + overlay on available space on USB stick"
  502.   echo "+ Size of live image:  $livesize"
  503.   [ "$overlaysizemb" -gt 0 ] && echo "+ Overlay size:  $overlaysizemb"
  504.   [ "$homesizemb" -gt 0 ] && echo "+ Home overlay size:  $homesizemb"
  505.   [ "$swapsizemb" -gt 0 ] && echo "+ Swap overlay size:  $swapsizemb"
  506.   echo "---------------------------"
  507.   echo "= Requested:  $tba"
  508.   echo "- Available:  $(($free + $tbd))"
  509.   echo "---------------------------"
  510.   echo "= To fit, free or decrease requested size total by:  $(($tba - $free - $tbd))"
  511.   exitclean
  512. fi
  513. fi
  514.  
  515. # Verify available space for DVD installer 
  516. if [ "$isotype" = "installer" ]; then
  517.   isosize=$(du -s -B 1M $ISO | awk {'print $1;'})
  518.   installimgsize=$(du -s -B 1M $CDMNT/images/install.img | awk {'print $1;'})
  519.   tbd=0
  520.   if [ -e $USBMNT/images/install.img ]; then
  521.     tbd=$(du -s -B 1M $USBMNT/images/install.img | awk {'print $1;'})
  522.   fi
  523.   if [ -e $USBMNT/$(basename $ISO) ]; then
  524.     tbd=$(($tbd + $(du -s -B 1M $USBMNT/$(basename $ISO) | awk {'print $1;'})))
  525.   fi
  526.   echo "Size of DVD image: $isosize"
  527.   echo "Size of install.img: $installimgsize"
  528.   echo "Available space: $(($free + $tbd))"
  529.   if [ $(($isosize + $installimgsize)) -gt $(($free + $tbd)) ]; then
  530.     echo "ERROR: Unable to fit DVD image + install.img on available space on USB stick"
  531.     exitclean
  532.   fi
  533. fi
  534.  
  535. if [ -z "$skipcopy" ] && [ "$isotype" = "live" ]; then
  536.   if [ -d $USBMNT/$LIVEOS -a -z "$force" ]; then
  537.       echo "Already set up as live image."  
  538.       if [ -z "$keephome" -a -e $USBMNT/$LIVEOS/$HOMEFILE ]; then
  539.         echo "WARNING: Persistent /home will be deleted!!!"
  540.         echo "Press Enter to continue or ctrl-c to abort"
  541.         read
  542.       else
  543.         echo "Deleting old OS in fifteen seconds..."
  544.         sleep 15
  545.  
  546.         [ -e "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" ] && mv $USBMNT/$LIVEOS/$HOMEFILE $USBMNT/$HOMEFILE
  547.       fi
  548.  
  549.       rm -rf $USBMNT/$LIVEOS
  550.   fi
  551. fi
  552.  
  553. # Bootloader is always reconfigured, so keep these out of the if skipcopy stuff.
  554. [ ! -d $USBMNT/$SYSLINUXPATH ] && mkdir -p $USBMNT/$SYSLINUXPATH
  555. [ -n "$efi" -a ! -d $USBMNT/EFI/boot ] && mkdir -p $USBMNT/EFI/boot
  556.  
  557. # Live image copy
  558. if [ -z "$skipcopy" ] && [ "$isotype" = "live" ]; then
  559.   echo "Copying live image to USB stick"
  560.   [ ! -d $USBMNT/$LIVEOS ] && mkdir $USBMNT/$LIVEOS
  561.   [ -n "$keephome" -a -f "$USBMNT/$HOMEFILE" ] && mv $USBMNT/$HOMEFILE $USBMNT/$LIVEOS/$HOMEFILE
  562.   if [ -n "$skipcompress" -a -f $CDMNT/LiveOS/squashfs.img ]; then
  563.       mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT || exitclean
  564.       cp $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || (umount $CDMNT ; exitclean)
  565.       umount $CDMNT
  566.   elif [ -f $CDMNT/LiveOS/squashfs.img ]; then
  567.       cp $CDMNT/LiveOS/squashfs.img $USBMNT/$LIVEOS/squashfs.img || exitclean
  568.   elif [ -f $CDMNT/LiveOS/ext3fs.img ]; then
  569.       cp $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || exitclean
  570.   fi
  571.   if [ -f $CDMNT/LiveOS/osmin.img ]; then
  572.       cp $CDMNT/LiveOS/osmin.img $USBMNT/$LIVEOS/osmin.img || exitclean
  573.   fi
  574. fi
  575.  
  576. # DVD installer copy
  577. if [ "$isotype" = "installer" ] && [ -z "$skipcopy" ]; then
  578.       echo "Copying DVD image to USB stick"
  579.       mkdir -p $USBMNT/images/
  580.       cp $CDMNT/images/install.img $USBMNT/images/install.img || exitclean
  581.       cp $ISO $USBMNT/
  582. fi
  583.  
  584. cp $CDMNT/isolinux/* $USBMNT/$SYSLINUXPATH
  585. BOOTCONFIG=$USBMNT/$SYSLINUXPATH/isolinux.cfg
  586. # Set this to nothing so sed doesn't care
  587. BOOTCONFIG_EFI=
  588. if [ -n "$efi" ];then
  589.   cp $CDMNT/EFI/boot/* $USBMNT/EFI/boot
  590.  
  591.   # this is a little ugly, but it gets the "interesting" named config file
  592.   BOOTCONFIG_EFI=$USBMNT/EFI/boot/boot?*.conf
  593.   rm -f $USBMNT/EFI/boot/grub.conf
  594. fi
  595.  
  596. echo "Updating boot config file"
  597. # adjust label and fstype
  598. sed -i -e "s/CDLABEL=[^ ]*/$USBLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$USBFS/" $BOOTCONFIG  $BOOTCONFIG_EFI
  599. if [ -n "$kernelargs" ]; then sed -i -e "s/liveimg/liveimg ${kernelargs}/" $BOOTCONFIG $BOOTCONFIG_EFI ; fi
  600. if [ "$LIVEOS" != "LiveOS" ]; then sed -i -e "s;liveimg;liveimg live_dir=$LIVEOS;" $BOOTCONFIG $BOOTCONFIG_EFI ; fi
  601.  
  602. # DVD Installer
  603. if [ "$isotype" = "installer" ]; then
  604.   sed -i -e "s;initrd=initrd.img;initrd=initrd.img repo=hd:$USBLABEL:/;g" $BOOTCONFIG $BOOTCONFIG_EFI
  605.   sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
  606. fi
  607.  
  608. if [ "$overlaysizemb" -gt 0 ]; then
  609.     echo "Initializing persistent overlay file"
  610.     OVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $USBDEV )-$( /sbin/blkid -s UUID -o value $USBDEV )"
  611.     if [ "$USBFS" = "vfat" ]; then
  612.     # vfat can't handle sparse files
  613.     dd if=/dev/zero of=$USBMNT/$LIVEOS/$OVERFILE count=$overlaysizemb bs=1M
  614.     else
  615.     dd if=/dev/null of=$USBMNT/$LIVEOS/$OVERFILE count=1 bs=1M seek=$overlaysizemb
  616.     fi
  617.     sed -i -e "s/liveimg/liveimg overlay=${USBLABEL}/" $BOOTCONFIG $BOOTCONFIG_EFI
  618.     sed -i -e "s/\ ro\ /\ rw\ /" $BOOTCONFIG  $BOOTCONFIG_EFI
  619. fi
  620.  
  621. if [ "$swapsizemb" -gt 0 ]; then
  622.     echo "Initializing swap file"
  623.     dd if=/dev/zero of=$USBMNT/$LIVEOS/swap.img count=$swapsizemb bs=1M
  624.     mkswap -f $USBMNT/$LIVEOS/swap.img
  625. fi
  626.  
  627. if [ "$homesizemb" -gt 0 ]; then
  628.     echo "Initializing persistent /home"
  629.     homesource=/dev/zero
  630.     [ -n "$cryptedhome" ] && homesource=/dev/urandom
  631.     if [ "$USBFS" = "vfat" ]; then
  632.     # vfat can't handle sparse files
  633.     dd if=${homesource} of=$USBMNT/$LIVEOS/$HOMEFILE count=$homesizemb bs=1M
  634.     else
  635.     dd if=/dev/null of=$USBMNT/$LIVEOS/$HOMEFILE count=1 bs=1M seek=$homesizemb
  636.     fi
  637.     if [ -n "$cryptedhome" ]; then
  638.     loop=$(losetup -f)
  639.     losetup $loop $USBMNT/$LIVEOS/$HOMEFILE
  640.     setupworked=1
  641.     until [ ${setupworked} == 0 ]; do
  642.             echo "Encrypting persistent /home"
  643.             cryptsetup luksFormat -y -q $loop
  644.         setupworked=$?
  645.     done
  646.     setupworked=1
  647.     until [ ${setupworked} == 0 ]; do
  648.             echo "Please enter the password again to unlock the device"
  649.             cryptsetup luksOpen $loop EncHomeFoo
  650.         setupworked=$?
  651.     done
  652.         mke2fs -j /dev/mapper/EncHomeFoo
  653.     tune2fs -c0 -i0 -ouser_xattr,acl /dev/mapper/EncHomeFoo
  654.     sleep 2
  655.         cryptsetup luksClose EncHomeFoo
  656.         losetup -d $loop
  657.     else
  658.         echo "Formatting unencrypted /home"
  659.     mke2fs -F -j $USBMNT/$LIVEOS/$HOMEFILE
  660.     tune2fs -c0 -i0 -ouser_xattr,acl $USBMNT/$LIVEOS/$HOMEFILE
  661.     fi
  662. fi
  663.  
  664. # create the forth files for booting on the XO if requested
  665. # we'd do this unconditionally, but you have to have a kernel that will
  666. # boot on the XO anyway.
  667. if [ -n "$xo" ]; then
  668.     echo "Setting up /boot/olpc.fth file"
  669.     args=$(egrep "^[ ]*append" $USBMNT/$SYSLINUXPATH/isolinux.cfg |head -n1 |sed -e 's/.*initrd=[^ ]*//')
  670.     if [ -z "$xonohome" -a ! -f $USBMNT/$LIVEOS/$HOMEFILE ]; then
  671.     args="$args persistenthome=mtd0"
  672.     fi
  673.     args="$args reset_overlay"
  674.     xosyspath=$(echo $SYSLINUXPATH | sed -e 's;/;\\;')
  675.     if [ ! -d $USBMNT/boot ]; then mkdir -p $USBMNT/boot ; fi
  676.     cat > $USBMNT/boot/olpc.fth <<EOF
  677. \ Boot script for USB boot
  678. hex  rom-pa fffc7 + 4 \$number drop  h# 2e19 < [if]
  679.   patch 2drop erase claim-params
  680.   : high-ramdisk  ( -- )
  681.      cv-load-ramdisk
  682.      h# 22c +lp l@ 1+   memory-limit  umin  /ramdisk - ffff.f000 and ( new-ramdisk-adr )
  683.      ramdisk-adr over  /ramdisk move                    ( new-ramdisk-adr )
  684.      to ramdisk-adr
  685.   ;
  686.   ' high-ramdisk to load-ramdisk
  687. [then]
  688.  
  689. : set-bootpath-dev  ( -- )
  690.    " /chosen" find-package  if                       ( phandle )
  691.       " bootpath" rot  get-package-property  0=  if  ( propval$ )
  692.          get-encoded-string                          ( bootpath$ )
  693.          [char] \ left-parse-string  2nip            ( dn$ )
  694.          dn-buf place                                ( )
  695.       then
  696.    then
  697.  
  698.    " /sd"  dn-buf  count  sindex  0>=   if
  699.           " sd:"
  700.    else
  701.           " u:"
  702.    then
  703.    " BOOTPATHDEV" \$set-macro
  704. ;
  705.  
  706. set-bootpath-dev
  707. " $args" to boot-file
  708. " \${BOOTPATHDEV}$xosyspath\initrd0.img" expand$ to ramdisk
  709. " \${BOOTPATHDEV}$xosyspath\vmlinuz0" expand$ to boot-device
  710. unfreeze
  711. boot
  712. EOF
  713.  
  714. fi
  715.  
  716. if [ -z "$multi" ]; then
  717.   echo "Installing boot loader"
  718.   if [ -n "$efi" ]; then
  719.     # replace the ia32 hack
  720.     if [ -f "$USBMNT/EFI/boot/boot.conf" ]; then cp -f $USBMNT/EFI/boot/bootia32.conf $USBMNT/EFI/boot/boot.conf ; fi
  721.   fi
  722.  
  723.   # this is a bit of a kludge, but syslinux doesn't guarantee the API for its com32 modules :/
  724.   if [ -f $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/share/syslinux/vesamenu.c32 ]; then
  725.     cp /usr/share/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
  726.   elif [ -f $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/lib/syslinux/vesamenu.c32 ]; then
  727.     cp /usr/lib/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
  728.   elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/share/syslinux/menu.c32 ]; then
  729.     cp /usr/share/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
  730.   elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/lib/syslinux/menu.c32 ]; then
  731.     cp /usr/lib/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
  732.   fi
  733.  
  734.   if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
  735.     # syslinux expects the config to be named syslinux.cfg 
  736.     # and has to run with the file system unmounted
  737.     mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
  738.     # deal with mtools complaining about ldlinux.sys
  739.     if [ -f $USBMNT/$SYSLINUXPATH/ldlinux.sys ] ; then rm -f $USBMNT/$SYSLINUXPATH/ldlinux.sys ; fi
  740.     cleanup
  741.     if [ -n "$SYSLINUXPATH" ]; then
  742.       syslinux -d $SYSLINUXPATH $USBDEV
  743.     else
  744.       syslinux $USBDEV
  745.     fi
  746.   elif [ "$USBFS" = "ext2" -o "$USBFS" = "ext3" ]; then
  747.     # extlinux expects the config to be named extlinux.conf
  748.     # and has to be run with the file system mounted
  749.     mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/extlinux.conf
  750.     extlinux -i $USBMNT/$SYSLINUXPATH
  751.     chattr -i $USBMNT/$SYSLINUXPATH/extlinux.sys
  752.     cleanup
  753.   fi
  754. else
  755.   # we need to do some more config file tweaks for multi-image mode
  756.   sed -i -e "s;kernel vm;kernel /$LIVEOS/syslinux/vm;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
  757.   sed -i -e "s;initrd=i;initrd=/$LIVEOS/syslinux/i;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
  758.   mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
  759.   cleanup
  760. fi
  761.  
  762. echo "USB stick set up as live image!"
  763.